/**
 * Copyright (C) 2009+ Spark Zheng
 *
 * @file        src/config.c 
 * @date        2010-04-05
 * @brief	server_framework
 * @see         dserver
 * @history
 */

#include <string.h>
#include <stdlib.h>

#include <dlib/str.h>
#include <dlib/confloose.h>
#include <dlib/mempool.h>

#include "config.h"

static inline int _main_conf_set_setting(dserver_setting_t *s);

static inline int _main_conf_set_setting(dserver_setting_t *s)
{
	int ret = RET_SUCCESS;
	dlib_confl_t *confl = s->dserver_confl;
	long integer;
	char *str;

	/* log path */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_LOG_PATH, CONFL_STR_COPY);
	if (str == NULL) {
		s->log_path = strdup(LOG_DIR);
	} else {
		s->log_path = str;
	}

	/* pid file */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_PID_FILE, CONFL_STR_COPY);
	if (str == NULL) {
		s->pid_file = strdup(DEF_PID_FILE);
	} else {
		s->pid_file = str;
	}

	/* max_fds */
	ret = dlib_confl_get_integer(confl, MAIN_FIELD, M_MAX_FDS, &integer);
	if (ret == -E_CONFL_FIELD_NOTEXIST || ret == -E_CONFL_ITEM_NOTEXIST) {
		s->max_fds = V_DEF_MAX_FDS;
	} else if (ret == 0) {
		s->max_fds = (uint32_t)integer;
	}

	/* max_conns */
	ret = dlib_confl_get_integer(confl, MAIN_FIELD, M_MAX_CONNS, &integer);
	if (ret == -E_CONFL_FIELD_NOTEXIST || ret == -E_CONFL_ITEM_NOTEXIST) {
		s->max_conns = V_DEF_MAX_CONNS;
	} else if (ret == 0) {
		s->max_conns = (uint32_t)integer;
	}

	/* rx_buf */
	ret = dlib_confl_get_integer(confl, MAIN_FIELD, M_RT_RX_BUF, &integer);
	if (ret == -E_CONFL_FIELD_NOTEXIST || ret == -E_CONFL_ITEM_NOTEXIST) {
		s->rx_buf = V_DEF_RX_BUF;
	} else if (ret == 0) {
		s->rx_buf = (uint32_t)integer;
	}

	/* tx_buf */
	ret = dlib_confl_get_integer(confl, MAIN_FIELD, M_RT_TX_BUF, &integer);
	if (ret == -E_CONFL_FIELD_NOTEXIST || ret == -E_CONFL_ITEM_NOTEXIST) {
		s->tx_buf = V_DEF_TX_BUF;
	} else if (ret == 0) {
		s->tx_buf = (uint32_t)integer;
	}

	/* user */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_USER, CONFL_STR_COPY);
	if (str == NULL) {
		s->user = strdup(V_DEF_USER);
	} else {
		s->user = str;
	}

	/* group */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_GROUP, CONFL_STR_COPY);
	if (str == NULL) {
		s->group = strdup(V_DEF_GROUP);
	} else {
		s->group = str;
	}

	/* protocols */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_PROTOCOLS, CONFL_STR_COPY);
	if (str == NULL) {
		s->protocols = strdup(V_DEF_PROTOCOLS);
	} else {
		s->protocols = str;
	}

	/* protocols_dir */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_PROTOCOLS_DIR, CONFL_STR_COPY);
	if (str == NULL) {
		s->protocols_dir = NULL;
	} else {
		s->protocols_dir = str;
	}

	/* filters */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_FILTERS, CONFL_STR_COPY);
	if (str == NULL) {
		s->filters = strdup(V_DEF_FILTERS);
	} else {
		s->filters = str;
	}

	/* filters_dir */
	str = dlib_confl_get_string(confl, MAIN_FIELD, M_FILTERS_DIR, CONFL_STR_COPY);
	if (str == NULL) {
		s->filters_dir = NULL;
	} else {
		s->filters_dir = str;
	}

	/* monitor host */
	str = dlib_confl_get_string(confl, MONT_FIELD, T_HOST, CONFL_STR_COPY);
	if (str == NULL) {
		s->mont_host = strdup(V_DEF_MHOST);
	} else {
		s->mont_host = str;
	}

	/* monitor port */
	ret = dlib_confl_get_integer(confl, MONT_FIELD, T_PORT, &integer);
	if (ret == -E_CONFL_FIELD_NOTEXIST || ret == -E_CONFL_ITEM_NOTEXIST) {
		s->mont_port = V_DEF_MPORT;
	} else if (ret == 0) {
		s->mont_port = (uint16_t)integer;
	}

	/* monitor timeout */
	ret = dlib_confl_get_integer(confl, MONT_FIELD, T_PORT, &integer);
	ret = dlib_confl_get_integer(confl, MONT_FIELD, T_TIMEOUT, &integer);
	if (ret == -E_CONFL_FIELD_NOTEXIST || ret == -E_CONFL_ITEM_NOTEXIST) {
		s->mont_timeout = V_DEF_MTIMEOUT;
	} else if (ret == 0) {
		s->mont_timeout = (uint16_t)integer;
	}

	/* monitor priority */
	ret = dlib_confl_get_integer(confl, MONT_FIELD, T_PRIORITY, &integer);
	if (ret == -E_CONFL_FIELD_NOTEXIST || ret == -E_CONFL_ITEM_NOTEXIST) {
		s->mont_priority = V_DEF_PRIORITY;
	} else if (ret == 0) {
		s->mont_priority = (uint16_t)integer;
	}

	return ret;
}

int main_conf_init(dserver_setting_t *s)
{
	if (s == NULL) {
		return -E_ARGS_ILLEGAL;
	}
	if (s->conf_file == NULL) {
		s->conf_file = strdup(DEF_CONF_FILE);
	}

	s->dserver_confl = dlib_confl_init(s->conf_file);
	if (s->dserver_confl == NULL) {
		return -E_UNEXPECTED;
	}

	return _main_conf_set_setting(s);
}

void main_conf_exit(dserver_setting_t *s)
{
	if (s == NULL) {
		return;
	}
	if (s->conf_file != NULL) {
		dfree(s->conf_file);
		s->conf_file = NULL;
	}
	if (s->log_path != NULL) {
		dfree(s->log_path);
		s->log_path = NULL;
	}
	if (s->pid_file != NULL) {
		dfree(s->pid_file);
		s->pid_file = NULL;
	}
	if (s->user != NULL) {
		dfree(s->user);
		s->user = NULL;
	}
	if (s->group != NULL) {
		dfree(s->group);
		s->group = NULL;
	}
	if (s->protocols != NULL) {
		dfree(s->protocols);
		s->protocols = NULL;
	}
	if (s->protocols_dir != NULL) {
		dfree(s->protocols_dir);
		s->protocols_dir = NULL;
	}
	if (s->filters != NULL) {
		dfree(s->filters);
		s->filters = NULL;
	}
	if (s->filters_dir != NULL) {
		dfree(s->filters_dir);
		s->filters_dir = NULL;
	}
	if (s->mont_host != NULL) {
		dfree(s->mont_host);
		s->mont_host = NULL;
	}

	if (s->dserver_confl != NULL) {
		dlib_confl_exit(s->dserver_confl);
		s->dserver_confl = NULL;
	}

	return;
}

void set_main_conf_file(const char *f, dserver_setting_t *s)
{
	if (f == NULL || s == NULL) {
		return;
	}
	uint32_t len = strlen(f);
	if (s->conf_file == NULL) {
		s->conf_file = dmalloc(len + 1);
		memcpy(s->conf_file, f, len);
		s->conf_file[len] = '\0';
	}
	return;
}
